﻿namespace MQtoUnity {
	using UnityEngine;
	using System.Collections;
	using System.Collections.Generic;

	public class VoxelData {

		public Color[] Palatte;

		public int SizeX, SizeY, SizeZ;

		public byte[] Version;

		public int[, ,] Voxels;

		public int VoxelNum {
			get {
				int num = 0;
				for (int i = 0; i < SizeX; i++) {
					for (int j = 0; j < SizeY; j++) {
						for (int k = 0; k < SizeZ; k++) {
							if (Voxels[i, j, k] != 0) {
								num++;
							}
						}
					}
				}
				return num;
			}
		}

	}


	public struct QbMatrix {

		public int this[int x, int y, int z] {
			get {
				return Voxels[x, y, z];
			}
		}
		public byte NameLength {
			get {
				return (byte)(string.IsNullOrEmpty(Name) ? 0 : Name.Length);
			}
		}
		public string Name;
		public int SizeX, SizeY, SizeZ;
		public int PosX, PosY, PosZ;
		public int[, ,] Voxels;

	}

	public class QbData {

		public uint Version;
		public uint ColorFormat; // 0->RGBA 1->BGRA
		public uint ZAxisOrientation; // 0->Left Handed  1->Right Handed
		public uint Compressed; // 0->Normal  1->WithNumbers
		public uint NumMatrixes;
		public uint VisibleMask;

		public List<QbMatrix> MatrixList;

		public Vector3 SizeAll {
			get {
				int SizeX = 0, SizeY = 0, SizeZ = 0;
				for (int i = 0; i < MatrixList.Count; i++) {
					if (i == 0) {
						SizeX = MatrixList[i].SizeX + MatrixList[i].PosX;
						SizeY = MatrixList[i].SizeY + MatrixList[i].PosY;
						SizeZ = MatrixList[i].SizeZ + MatrixList[i].PosZ;
					} else {
						SizeX = Mathf.Max(SizeX, MatrixList[i].SizeX + MatrixList[i].PosX);
						SizeY = Mathf.Max(SizeY, MatrixList[i].SizeY + MatrixList[i].PosY);
						SizeZ = Mathf.Max(SizeZ, MatrixList[i].SizeZ + MatrixList[i].PosZ);
					}
				}
				return new Vector3(SizeX, SizeY, SizeZ);
			}
		}

		public VoxelData GetVoxData () {

			VoxelData vox = new VoxelData();

			Vector3 sizeAll = SizeAll;
			vox.SizeX = (int)sizeAll.x;
			vox.SizeY = (int)sizeAll.y;
			vox.SizeZ = (int)sizeAll.z;

			vox.Voxels = new int[vox.SizeX, vox.SizeY, vox.SizeZ];
			List<Color> pl = new List<Color>();
			pl.Add(new Color());

			for (int i = 0; i < MatrixList.Count; i++) {
				for (int x = 0; x < MatrixList[i].SizeX; x++) {
					for (int y = 0; y < MatrixList[i].SizeY; y++) {
						for (int z = 0; z < MatrixList[i].SizeZ; z++) {
							int v = MatrixList[i][x, y, z];
							if (v != 0) {
								Color color = ColorFormat == 0 ? RGB(v) : BGR(v);
								int index = pl.IndexOf(color);
								if (index == -1) {
									pl.Add(color);
									index = pl.Count - 1;
								}
								vox.Voxels[x + MatrixList[i].PosX, y + MatrixList[i].PosY, z + MatrixList[i].PosZ] = index + 1;
							}
						}
					}
				}
			}

			vox.Palatte = pl.ToArray();
			return vox;
		}






		private Color RGB (int color) {
			int r = 0xFF & color;
			int g = 0xFF00 & color;
			g >>= 8;
			int b = 0xFF0000 & color;
			b >>= 16;
			return new Color((float)r / 255f, (float)g / 255f, (float)b / 255f);
		}

		private Color BGR (int color) {
			int b = 0xFF & color;
			int g = 0xFF00 & color;
			g >>= 8;
			int r = 0xFF0000 & color;
			r >>= 16;
			return new Color((float)r / 255f, (float)g / 255f, (float)b / 255f);
		}



	}
}